package com.suixun.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.annotation.Resource;

import org.apache.commons.collections.CollectionUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.suixun.dao.BannerDAO;
import com.suixun.dao.BannerMapper;
import com.suixun.entity.Banner;
import com.suixun.entity.BannerExample;
import com.suixun.entity.page.PageModel;
import com.suixun.exception.OpServiceException;
import com.suixun.service.BannerService;
import com.suixun.service.cache.CacheService;
import com.suixun.util.DateUtil;
import com.suixun.vo.BannerVO;

import rop.thirdparty.org.apache.commons.lang3.StringUtils;

@Service
public class BannerServiceImpl implements BannerService {
	@Resource
	private BannerMapper bannerMapper;
	@Resource
	private BannerDAO bannerDAO;
	@Resource
	private CacheService cacheService;

	@Override
	public String addBanner(BannerVO banner) {
		if (banner == null) {
			return "广告内容不能为空";
		}
		if (StringUtils.isBlank(banner.getBannerUrl())) {
			return "广告图片不能为空";
		}
		if (StringUtils.isBlank(banner.getContent())) {
			return "广告内容不能为空";
		}
		if (StringUtils.isBlank(banner.getTitle())) {
			return "广告标题不能为空";
		}
		if (banner.getType() == null) {
			return "展示类型不能为空";
		}
		if (banner.getIsShow() == null) {
			return "展示状态不能为空";
		}
		if (banner.getIndex() == null) {
			return "广告栏位不能为空";
		}
		Date beginTime = banner.getStartTime() == null ? null
				: DateUtil.formatStringToTime(banner.getStartTime(), "yyyy-MM-dd HH:mm:ss");
		Date endTime = banner.getEndTime() == null ? null
				: DateUtil.formatStringToTime(banner.getEndTime(), "yyyy-MM-dd HH:mm:ss");
		Date nowDate = new Date();
		Short displayType = Short.parseShort(banner.getType().toString());
		Short isShow = Short.parseShort(banner.getIsShow().toString());
		if (endTime != null && endTime.compareTo(nowDate) == -1 && "1".equals(String.valueOf(isShow))) {
			return "展示结束时间不符";
		}
		Integer bannerRange = 1;
		if (banner.getBannerRange() != null) {
			bannerRange = banner.getBannerRange();
		}
		if ("1".equals(String.valueOf(isShow))) {
			// 判断当前栏位是否已有有效展示的，若有，则关闭其他已展示的
			updateDisplayByIndex(banner.getIndex(), bannerRange);
			if (!checkDisplayBannerIsFull(bannerRange)) {
				return "广告位已满";
			}
		}

		Banner bannerDo = new Banner();
		bannerDo.setBannerRange((short) bannerRange.intValue());
		bannerDo.setBannerUrl(banner.getBannerUrl());
		bannerDo.setBeginTime(beginTime);
		bannerDo.setEndTime(endTime);
		bannerDo.setDisplayContent(banner.getContent());
		bannerDo.setIsshow(isShow);
		bannerDo.setpIndex(banner.getIndex());
		bannerDo.setTheme(banner.getTitle());
		bannerDo.setDisplayType(displayType);
		bannerMapper.insertSelective(bannerDo);
		// 清缓存
		cacheService.flushBannerList();
		return null;
	}

	@Override
	@Transactional
	public String updateBanner(BannerVO banner) {
		if (banner == null) {
			return null;
		}
		if (banner.getBannerId() == null) {
			return "广告id不能为空";
		}
		if (banner.getIndex() == null) {
			return "广告栏位不能为空";
		}
		Banner bannerDo = bannerMapper.selectByPrimaryKey(banner.getBannerId());
		if (bannerDo == null) {
			return "广告不存在";
		}
		Date beginTime = banner.getStartTime() == null ? null
				: DateUtil.formatStringToTime(banner.getStartTime(), "yyyy-MM-dd HH:mm:ss");
		Date endTime = banner.getEndTime() == null ? null
				: DateUtil.formatStringToTime(banner.getEndTime(), "yyyy-MM-dd HH:mm:ss");
		Date nowDate = new Date();
		Short displayType = banner.getType() == null ? null : Short.parseShort(banner.getType().toString());
		Short isShow = banner.getIsShow() == null ? null : Short.parseShort(banner.getIsShow().toString());
		
		Integer bannerRange = 1;
		if (banner.getBannerRange() != null) {
			bannerRange = banner.getBannerRange();
		}
		if ("0".equals(String.valueOf(bannerDo.getIsshow())) && "1".equals(String.valueOf(isShow))) {
			if (endTime != null && endTime.compareTo(nowDate) == -1) {
				return "展示结束时间不符";
			}
			// 如果当前index下有效展示的广告，则将其isshow置为0
			updateDisplayByIndex(banner.getIndex(), bannerRange);
			if (!checkDisplayBannerIsFull(bannerRange)) {
				return "广告位已满";
			}
		}
		Banner bannerTemp = new Banner();
		bannerTemp.setBannerUrl(banner.getBannerUrl());
		bannerTemp.setBeginTime(beginTime);
		bannerTemp.setEndTime(endTime);
		bannerTemp.setDisplayContent(banner.getContent());
		bannerTemp.setId(banner.getBannerId());
		bannerTemp.setDisplayType(displayType);
		bannerTemp.setIsshow(isShow);
		bannerTemp.setpIndex(banner.getIndex());
		bannerTemp.setTheme(banner.getTitle());
		if (banner.getBannerRange() != null) {
			bannerTemp.setBannerRange((short)bannerRange.intValue());
		}
		bannerMapper.updateByPrimaryKeySelective(bannerTemp);
		// 清缓存
		cacheService.flushBannerList();
		cacheService.flushBannerDetail(banner.getBannerId());
		return null;
	}

	@Override
	@Transactional
	public String deleteBanner(String bannerIds) {
		if (StringUtils.isBlank(bannerIds)) {
			return "广告id不能为空";
		}
		String[] bannerIdArr = bannerIds.split("[|]");
		Banner bannerDo = null;
		for (String bannerId : bannerIdArr) {
			final Integer id = Integer.parseInt(bannerId);
			bannerDo = bannerMapper.selectByPrimaryKey(id);
			if (bannerDo == null) {
				throw new OpServiceException("广告不存在");
			}
			bannerMapper.deleteByPrimaryKey(id);
		}
		for (String bannerId : bannerIdArr) {
			cacheService.flushBannerDetail(Integer.parseInt(bannerId));
		}
		cacheService.flushBannerList();
		return null;
	}

	@Override
	public PageModel<BannerVO> getBannerPage(Integer pageNumber, Integer pagSize, Integer index) {
		PageModel<BannerVO> pageModel = new PageModel<>();
		BannerExample bannerExample = new BannerExample();
		bannerExample.createCriteria().andPIndexEqualTo(index);
		int totleRows = bannerMapper.countByExample(bannerExample);
		pageModel.setPagesize(pagSize);
		pageModel.setTotlepage(totleRows);
		pageModel.setCurrentpage(pageNumber);
		pageModel.getQueryparam().put("index", index);
		List<Banner> bannerList = bannerDAO.getBannerPage(pageModel);
		if (CollectionUtils.isEmpty(bannerList)) {
			return pageModel;
		}
		List<BannerVO> bannerVoList = new ArrayList<>();
		BannerVO bannerVo = null;
		for (Banner bannerDo : bannerList) {
			bannerVo = new BannerVO();
			bannerVo.setBannerId(bannerDo.getId());
			bannerVo.setBannerUrl(bannerDo.getBannerUrl());
			bannerVo.setContent(bannerDo.getDisplayContent());
			bannerVo.setEndTime(
					bannerDo.getEndTime() == null ? null : DateUtil.formatDateToString(bannerDo.getEndTime(), null));
			bannerVo.setIndex(bannerDo.getpIndex());
			bannerVo.setIsShow(Integer.parseInt(bannerDo.getIsshow().toString()));
			bannerVo.setStartTime(bannerDo.getBeginTime() == null ? null
					: DateUtil.formatDateToString(bannerDo.getBeginTime(), null));
			bannerVo.setTitle(bannerDo.getTheme());
			bannerVo.setType(Integer.parseInt(bannerDo.getDisplayType().toString()));
			bannerVoList.add(bannerVo);
		}
		pageModel.setQueryresult(bannerVoList);
		return pageModel;
	}

	/**
	 * 
	 * <p>
	 * Title: checkDisplayBannerIsFull
	 * </p>
	 * <p>
	 * 功能描述: 检查广告位是否已满
	 * </p>
	 * 
	 * @return
	 */
	private boolean checkDisplayBannerIsFull() {
		// 判断已展示的广告是否已经有五张，展示的广告不能超过5张
		BannerExample bannerExample = new BannerExample();
		Date nowDate = new Date();
		bannerExample.createCriteria().andIsshowEqualTo((short) 1).andBeginTimeLessThan(nowDate)
				.andEndTimeGreaterThan(nowDate);
		int displayBannerCountByTime = bannerMapper.countByExample(bannerExample);
		bannerExample = new BannerExample();
		bannerExample.createCriteria().andIsshowEqualTo((short) 1).andBeginTimeIsNull().andEndTimeIsNull();
		int displayBannerCountByNoTime = bannerMapper.countByExample(bannerExample);
		if (displayBannerCountByTime + displayBannerCountByNoTime == 5) {
			return false;
		}
		return true;
	}

	private boolean checkDisplayBannerIsFull(Integer bannerRange) {
		// 判断已展示的广告是否已经有五张，展示的广告不能超过5张
		BannerExample bannerExample = new BannerExample();
		Date nowDate = new Date();
		bannerExample.createCriteria().andIsshowEqualTo((short) 1).andBeginTimeLessThan(nowDate)
				.andEndTimeGreaterThan(nowDate).andBannerRangeEqualTo((short) bannerRange.intValue());
		int displayBannerCountByTime = bannerMapper.countByExample(bannerExample);
		bannerExample = new BannerExample();
		bannerExample.createCriteria().andIsshowEqualTo((short) 1).andBeginTimeIsNull().andEndTimeIsNull()
				.andBannerRangeEqualTo((short) bannerRange.intValue());
		int displayBannerCountByNoTime = bannerMapper.countByExample(bannerExample);
		if (displayBannerCountByTime + displayBannerCountByNoTime == 5) {
			return false;
		}
		return true;
	}

	/**
	 * <p>
	 * Title: updateDisplayByIndex
	 * </p>
	 * <p>
	 * 功能描述: 修改当前栏位下正处于有效展示的banner，将其改为隐藏
	 * </p>
	 * 
	 * @param index
	 */
	private void updateDisplayByIndex(Integer index) {
		BannerExample bannerExample = new BannerExample();
		bannerExample.createCriteria().andPIndexEqualTo(index);
		Banner banner = new Banner();
		banner.setIsshow((short) 0);
		bannerMapper.updateByExampleSelective(banner, bannerExample);

		/*
		 * Date nowDate = new Date();
		 * bannerExample.createCriteria().andIsshowEqualTo((short)
		 * 1).andBeginTimeLessThan(nowDate)
		 * .andEndTimeGreaterThan(nowDate).andPIndexEqualTo(index); int
		 * displayBannerCountByTime =
		 * bannerMapper.countByExample(bannerExample); Banner bannerTemp = new
		 * Banner(); if (displayBannerCountByTime > 0) {
		 * bannerTemp.setIsshow((short) 0);
		 * bannerMapper.updateByExampleSelective(bannerTemp, bannerExample); }
		 * bannerExample = new BannerExample();
		 * bannerExample.createCriteria().andIsshowEqualTo((short)
		 * 1).andBeginTimeIsNull().andEndTimeIsNull(); int
		 * displayBannerCountByNoTime =
		 * bannerMapper.countByExample(bannerExample); if
		 * (displayBannerCountByNoTime > 0) { bannerTemp.setIsshow((short) 0);
		 * bannerMapper.updateByExampleSelective(bannerTemp, bannerExample); }
		 */
	}
	
	private void updateDisplayByIndex(Integer index, Integer bannerRange) {
		BannerExample bannerExample = new BannerExample();
		bannerExample.createCriteria().andPIndexEqualTo(index).andBannerRangeEqualTo((short)bannerRange.intValue());
		Banner banner = new Banner();
		banner.setIsshow((short) 0);
		bannerMapper.updateByExampleSelective(banner, bannerExample);
	}

	@Override
	public BannerVO getBanner(Integer bannerId) {
		if (bannerId == null) {
			return null;
		}
		Banner bannerDo = bannerMapper.selectByPrimaryKey(bannerId);
		if (bannerDo == null) {
			return null;
		}
		BannerVO bannerVo = new BannerVO();
		bannerVo.setBannerRange(bannerDo.getBannerRange().intValue());
		bannerVo.setBannerId(bannerDo.getId());
		bannerVo.setBannerUrl(bannerDo.getBannerUrl());
		bannerVo.setContent(bannerDo.getDisplayContent());
		bannerVo.setEndTime(DateUtil.formatDateToString(bannerDo.getEndTime(), "yyyy-MM-dd HH:mm:ss"));
		bannerVo.setIndex(bannerDo.getpIndex());
		bannerVo.setIsShow(Integer.parseInt(String.valueOf(bannerDo.getIsshow())));
		bannerVo.setStartTime(DateUtil.formatDateToString(bannerDo.getBeginTime(), "yyyy-MM-dd HH:mm:ss"));
		bannerVo.setTitle(bannerDo.getTheme());
		bannerVo.setType(
				bannerDo.getDisplayType() == null ? null : Integer.parseInt(bannerDo.getDisplayType().toString()));
		return bannerVo;
	}

	@Override
	public PageModel<BannerVO> getBannerPage(Integer pageNumber, Integer pagSize, Integer index, Integer bannerRange) {
		PageModel<BannerVO> pageModel = new PageModel<>();
		BannerExample bannerExample = new BannerExample();
		bannerExample.createCriteria().andPIndexEqualTo(index).andBannerRangeEqualTo((short) bannerRange.intValue());
		int totleRows = bannerMapper.countByExample(bannerExample);
		pageModel.setPagesize(pagSize);
		pageModel.setTotlepage(totleRows);
		pageModel.setCurrentpage(pageNumber);
		pageModel.getQueryparam().put("index", index);
		pageModel.getQueryparam().put("bannerRange", bannerRange);
		List<Banner> bannerList = bannerDAO.getBannerPage(pageModel);
		if (CollectionUtils.isEmpty(bannerList)) {
			return pageModel;
		}
		List<BannerVO> bannerVoList = new ArrayList<>();
		BannerVO bannerVo = null;
		for (Banner bannerDo : bannerList) {
			bannerVo = new BannerVO();
			bannerVo.setBannerRange(bannerDo.getBannerRange().intValue());
			bannerVo.setBannerId(bannerDo.getId());
			bannerVo.setBannerUrl(bannerDo.getBannerUrl());
			bannerVo.setContent(bannerDo.getDisplayContent());
			bannerVo.setEndTime(
					bannerDo.getEndTime() == null ? null : DateUtil.formatDateToString(bannerDo.getEndTime(), null));
			bannerVo.setIndex(bannerDo.getpIndex());
			bannerVo.setIsShow(Integer.parseInt(bannerDo.getIsshow().toString()));
			bannerVo.setStartTime(bannerDo.getBeginTime() == null ? null
					: DateUtil.formatDateToString(bannerDo.getBeginTime(), null));
			bannerVo.setTitle(bannerDo.getTheme());
			bannerVo.setType(Integer.parseInt(bannerDo.getDisplayType().toString()));
			bannerVoList.add(bannerVo);
		}
		pageModel.setQueryresult(bannerVoList);
		return pageModel;
	}
}
